Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / Sideband.git / files / sbapp / kivymd / uix / behaviors / hover_behavior.py

Displaying Raw • Download


sbapp/kivymd/uix/behaviors/hover_behavior.py 0.2.2 (399da923) Text, 7.72 KB

T8b949e"""
Behaviors/Hover
===============

.. rubric:: Changing when the mouse is on the widget and the widget is visible.

To apply hover behavior, you must create a new class that is inherited from the
widget to which you apply the behavior and from the :attr:`HoverBehavior` class.

In `KV file`:

.. code-block:: kv

<HoverItem@MDBoxLayout+ThemableBehavior+HoverBehavior>

In `python file`:

.. code-block:: python

class HoverItem(MDBoxLayout, ThemableBehavior, HoverBehavior):
'''Custom item implementing hover behavior.'''

After creating a class, you must define two methods for it:
:attr:`HoverBehavior.on_enter` and :attr:`HoverBehavior.on_leave`, which will be automatically called
when the mouse cursor is over the widget and when the mouse cursor goes beyond
the widget.

.. note::

:class:`~HoverBehavior` will by default check to see if the current Widget is visible (i.e. not covered by a modal or popup and not a part of a Relative Layout, MDTab or Carousel that is not currently visible etc) and will only issue events if the widget is visible.

To get the legacy behavior that the events are always triggered, you can set `detect_visible` on the Widget to `False`.

.. code-block:: python

from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.behaviors import HoverBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.theming import ThemableBehavior

KV = '''
Screen

MDBoxLayout:
id: box
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: .8, .8
md_bg_color: app.theme_cls.bg_darkest
'''


class HoverItem(MDBoxLayout, ThemableBehavior, HoverBehavior):
'''Custom item implementing hover behavior.'''

def on_enter(self, *args):
'''The method will be called when the mouse cursor
is within the borders of the current widget.'''

self.md_bg_color = (1, 1, 1, 1)

def on_leave(self, *args):
'''The method will be called when the mouse cursor goes beyond
the borders of the current widget.'''

self.md_bg_color = self.theme_cls.bg_darkest


class Test(MDApp):
def build(self):
self.screen = Builder.load_string(KV)
for i in range(5):
self.screen.ids.box.add_widget(HoverItem())
return self.screen


Test().run()

.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/hover-behavior.gif
:width: 250 px
:align: center
"""

Te6edf3__all__ Tff7b72= Tb4b4b4(Ta5d6ff"Ta5d6ffHoverBehaviorTa5d6ff"Tb4b4b4,Tb4b4b4)

Tff7b72from T7ee787kivyT7ee787.T7ee787coreT7ee787.T7ee787window Tff7b72import Te6edf3Window
Tff7b72from T7ee787kivyT7ee787.T7ee787properties Tff7b72import Te6edf3BooleanPropertyTb4b4b4, Te6edf3ObjectProperty
Tff7b72from T7ee787kivyT7ee787.T7ee787uixT7ee787.T7ee787widget Tff7b72import Te6edf3Widget


Tff7b72class T56d364HoverBehaviorTb4b4b4(Tffa657objectTb4b4b4)Tb4b4b4:
T8b949e"""
:Events:
:attr:`on_enter`
Called when mouse enters the bbox of the widget AND the widget is visible
:attr:`on_leave`
Called when the mouse exits the widget AND the widget is visible
"""

Te6edf3hovering Tff7b72= Te6edf3BooleanPropertyTb4b4b4(Tff7b72FalseTb4b4b4)
T8b949e"""
`True`, if the mouse cursor is within the borders of the widget.

Note that this is set and cleared even if the widget is not visible

:attr:`hover` is a :class:`~kivy.properties.BooleanProperty`
and defaults to `False`.
"""

Te6edf3hover_visible Tff7b72= Te6edf3BooleanPropertyTb4b4b4(Tff7b72FalseTb4b4b4)
T8b949e"""
`True` if hovering is True AND is the current widget is visible

:attr:`hover_visible` is a :class:`~kivy.properties.BooleanProperty`
and defaults to `False`.
"""

Te6edf3enter_point Tff7b72= Te6edf3ObjectPropertyTb4b4b4(Te6edf3allownoneTff7b72=Tff7b72TrueTb4b4b4)
T8b949e"""
Holds the last position where the mouse pointer crossed into the Widget
if the Widget is visible and is currently in a hovering state

:attr:`enter_point` is a :class:`~kivy.properties.ObjectProperty`
and defaults to `None`.
"""

Te6edf3detect_visible Tff7b72= Te6edf3BooleanPropertyTb4b4b4(Tff7b72TrueTb4b4b4)
T8b949e"""
Should this widget perform the visibility check?

:attr:`detect_visible` is a :class:`~kivy.properties.BooleanProperty`
and defaults to `True`.
"""

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffregister_event_typeTb4b4b4(Ta5d6ff"Ta5d6ffon_enterTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffregister_event_typeTb4b4b4(Ta5d6ff"Ta5d6ffon_leaveTa5d6ff"Tb4b4b4)
Te6edf3WindowTff7b72.Td2a8ffbindTb4b4b4(Te6edf3mouse_posTff7b72=Tff7b72selfTff7b72.Td2a8ffon_mouse_updateTb4b4b4)
Tffa657superTb4b4b4(Te6edf3HoverBehaviorTb4b4b4, Tff7b72selfTb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)

Tff7b72def Td2a8ffon_mouse_updateTb4b4b4(Tff7b72selfTb4b4b4, Tff7b72*Te6edf3argsTb4b4b4)Tb4b4b4:
T8b949e# If the Widget currently has no parent, do nothing
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffget_root_windowTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3pos Tff7b72= Te6edf3argsTb4b4b4[T79c0ff1Tb4b4b4]
T8b949e#
T8b949e# is the pointer in the same position as the widget?
T8b949e# If not - then issue an on_exit event if needed
T8b949e#
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffcollide_pointTb4b4b4(Tff7b72*Tff7b72selfTff7b72.Td2a8ffto_widgetTb4b4b4(Tff7b72*Te6edf3posTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhovering Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffenter_point Tff7b72= Tff7b72None
Tff7b72if Tff7b72selfTff7b72.Td2a8ffhover_visibleTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhover_visible Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffdispatchTb4b4b4(Ta5d6ff"Ta5d6ffon_leaveTa5d6ff"Tb4b4b4)
Tff7b72return

T8b949e#
T8b949e# The pointer is in the same position as the widget
T8b949e#

Tff7b72if Tff7b72selfTff7b72.Td2a8ffhoveringTb4b4b4:
T8b949e#
T8b949e# nothing to do here. Not - this does not handle the case where
T8b949e# a popup comes over an existing hover event.
T8b949e# This seems reasonable
T8b949e#
Tff7b72return

T8b949e#
T8b949e# Otherwise - set the hovering attribute
T8b949e#
Tff7b72selfTff7b72.Td2a8ffhovering Tff7b72= Tff7b72True

T8b949e#
T8b949e# We need to traverse the tree to see if the Widget is visible
T8b949e#
T8b949e# This is a two stage process:
T8b949e# - first go up the tree to the root Window.
T8b949e# At each stage - check that the Widget is actually visible
T8b949e# - Second - At the root Window check that there is not another branch
T8b949e# covering the Widget
T8b949e#

Tff7b72selfTff7b72.Td2a8ffhover_visible Tff7b72= Tff7b72True
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdetect_visibleTb4b4b4:
Te6edf3widgetTb4b4b4: Te6edf3Widget Tff7b72= Tff7b72self
Tff7b72while Tff7b72TrueTb4b4b4:
T8b949e# Walk up the Widget tree from the target Widget
Te6edf3parent Tff7b72= Te6edf3widgetTff7b72.Td2a8ffparent
Tff7b72tryTb4b4b4:
T8b949e# See if the mouse point collides with the parent
T8b949e# using both local and glabal coordinates to cover absoluet and relative layouts
Te6edf3pinside Tff7b72= Te6edf3parentTff7b72.Td2a8ffcollide_pointTb4b4b4(
Tff7b72*Te6edf3parentTff7b72.Td2a8ffto_widgetTb4b4b4(Tff7b72*Te6edf3posTb4b4b4)
Tb4b4b4) Tff7b72or Te6edf3parentTff7b72.Td2a8ffcollide_pointTb4b4b4(Tff7b72*Te6edf3posTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
T8b949e# The collide_point will error when you reach the root Window
Tff7b72break
Tff7b72if Tff7b72not Te6edf3pinsideTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhover_visible Tff7b72= Tff7b72False
Tff7b72break
T8b949e# Iterate upwards
Te6edf3widget Tff7b72= Te6edf3parent

T8b949e#
T8b949e# parent = root window
T8b949e# widget = first Widget on the current branch
T8b949e#

Te6edf3children Tff7b72= Te6edf3parentTff7b72.Td2a8ffchildren
Tff7b72for Te6edf3child Tff7b72in Te6edf3childrenTb4b4b4:
T8b949e# For each top level widget - check if is current branch
T8b949e# If it is - then break.
T8b949e# If not then - since we start at 0 - this widget is visible
T8b949e#
T8b949e# Check to see if it should take the hover
T8b949e#
Tff7b72if Te6edf3child Tff7b72== Te6edf3widgetTb4b4b4:
T8b949e# this means that the current widget is visible
Tff7b72break
Tff7b72if Te6edf3childTff7b72.Td2a8ffcollide_pointTb4b4b4(Tff7b72*Te6edf3posTb4b4b4)Tb4b4b4:
T8b949e# this means that the current widget is covered by a modal or popup
Tff7b72selfTff7b72.Td2a8ffhover_visible Tff7b72= Tff7b72False
Tff7b72break
Tff7b72if Tff7b72selfTff7b72.Td2a8ffhover_visibleTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffenter_point Tff7b72= Te6edf3pos
Tff7b72selfTff7b72.Td2a8ffdispatchTb4b4b4(Ta5d6ff"Ta5d6ffon_enterTa5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffon_enterTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Called when mouse enters the bbox of the widget AND the widget is visible."""

Tff7b72def Td2a8ffon_leaveTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Called when the mouse exits the widget AND the widget is visible."""


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────